package first.endtoend.tsm.webservices;

import first.endtoend.tsm.TSMHelper;
import first.endtoend.tsm.TSMHelperTools;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.GpFunctions;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.IServiceEvents;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.ksoap2.elements.OperationResult;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.ksoap2.services.types.ServiceInstanceReferenceType;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.ksoap2.services.types.commands.ServiceCommandType;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.ksoap2.services.types.requests.DeclareServiceInstanceReferenceRequestType;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.ksoap2.services.types.requests.SuspendOrResumeServiceRequestType;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.ksoap2.services.types.requests.TerminateServiceRequestType;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.ksoap2.services.types.requests.UpgradeServiceRequestType;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.ksoap2.services.types.requests.data.DeclareServiceInstanceReferenceResponseDataType;
import org.mbds.wolf.tsm.gp.systems.messaging2_1_0.ksoap2.services.types.requests.responses.DeclareServiceInstanceReferenceResponseType;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * Created by ncordina on 19/06/2015.
 */
public class GlobalServiceManagement extends TSMHelper implements IServiceEvents
{

    private HashMap<String, String> displayServiceInstance = new HashMap<String, String>();
    private HashMap<String, String> displaySusPendOrResume = new HashMap<String, String>();
    private HashMap<String, String> displayTerminateService = new HashMap<String, String>();
    private HashMap<String, String> displayUpgradeService = new HashMap<String, String>();

    /**
     * Class Constructor
     * Take the URL of SPTSM Server in parameter and instanciate the CallBack and the controller of Wolf library
     *
     * @param URL
     */
    public GlobalServiceManagement(String URL)
    {
        super(URL);
    }

    @Override
    public void Starting()
    {
        logger.debug("Starting GlobalService Management CallBack");
    }

    @Override
    public synchronized void Completed(OperationResult operationResult)
    {
        logger.debug("Completed GlobalService Management CallBack");
        if (operationResult.MethodName.equalsIgnoreCase(GpFunctions.DeclareServiceInstanceReference.getFunction()))
        {
            this.getDeclareServiceInstanceReferenceResponse(operationResult);
            notify();
        }
        if (operationResult.MethodName.equalsIgnoreCase(GpFunctions.SuspendOrResumeService.getFunction()))
        {
            displaySusPendOrResume = TSMHelperTools.handleResponse(operationResult, GpFunctions.SuspendOrResumeService.getFunction());
            notify();
        }
        if (operationResult.MethodName.equalsIgnoreCase(GpFunctions.TerminateService.getFunction()))
        {
            displayTerminateService = TSMHelperTools.handleResponse(operationResult, GpFunctions.TerminateService.getFunction());
            notify();
        }
        if (operationResult.MethodName.equalsIgnoreCase(GpFunctions.UpgradeService.getFunction()))
        {
            displayUpgradeService = TSMHelperTools.handleResponse(operationResult, GpFunctions.UpgradeService.getFunction());
            notify();
        }

    }

    /**
     * Call webservice
     *
     * @return an HashMap with all datas
     * @throws InterruptedException
     */
    public synchronized HashMap<String, String> declareServiceInstanceReference() throws InterruptedException
    {
        DeclareServiceInstanceReferenceRequestType declareServiceInstanceReferenceRequestType = new DeclareServiceInstanceReferenceRequestType();
        declareServiceInstanceReferenceRequestType.FunctionCallIdentifier = GpFunctions.DeclareServiceInstanceReference.getFunction();
        declareServiceInstanceReferenceRequestType.ServiceInstanceReference = tools.initServiceReferenceType();
        declareServiceInstanceReferenceRequestType.Service = tools.initService();
        declareServiceInstanceReferenceRequestType.ServiceQualifier = tools.initServiceQualifier();
        declareServiceInstanceReferenceRequestType.SecureElement = tools.initSecureElement();
        declareServiceInstanceReferenceRequestType.MobileSubscription = tools.initMobileSubcription();

        tsmController.DeclareServiceInstanceReference(this, declareServiceInstanceReferenceRequestType);
        wait();
        return displayServiceInstance;
    }

    /**
     * Suspend or resume a test service
     *
     * @param suspended
     * @return
     * @throws InterruptedException
     */
    public synchronized HashMap<String, String> suspendOrResumeService(boolean suspended) throws InterruptedException
    {
        SuspendOrResumeServiceRequestType suspendOrResumeServiceRequestType = new SuspendOrResumeServiceRequestType();
        suspendOrResumeServiceRequestType.ServiceInstanceReference = tools.initServiceReferenceType();
        suspendOrResumeServiceRequestType.SuspensionControl = suspended; //true = SUSPEND service, FALSE = resume

        //tsmController.SuspendOrResumeService(this,suspendOrResumeServiceRequestType); //TODO demander a Anne-Marie de coder ce webservice.
        wait();
        return displaySusPendOrResume;
    }

    /**
     * Suspend or Resume a given service
     *
     * @param serviceInstanceReferenceType The service to suspend/resume
     * @param suspended                    True if SUSPEND, False if Resume
     * @return
     * @throws InterruptedException
     */
    public synchronized HashMap<String, String> suspendOrResumeService(ServiceInstanceReferenceType serviceInstanceReferenceType, boolean suspended) throws InterruptedException
    {
        SuspendOrResumeServiceRequestType suspendOrResumeServiceRequestType = new SuspendOrResumeServiceRequestType();
        suspendOrResumeServiceRequestType.ServiceInstanceReference = serviceInstanceReferenceType;
        suspendOrResumeServiceRequestType.SuspensionControl = suspended; //true = SUSPEND service, FALSE = resume

        //tsmController.SuspendOrResumeService(this,suspendOrResumeServiceRequestType); //TODO demander a Anne-Marie de coder ce webservice.
        wait();
        return displaySusPendOrResume;
    }

    /**
     * Call the webservice, take a request object in parameter
     * @param declareServiceInstanceReferenceRequestType The request to send to the TSM
     * @return a Hashmap with responses data
     * @throws InterruptedException
     */

    /**
     * Call the webservice, take a request object in parameter
     *
     * @param declareServiceInstanceReferenceRequestType The request to send to the TSM
     * @return a Hashmap with responses data
     * @throws InterruptedException
     */
    public synchronized HashMap<String, String> declareServiceInstanceReference(DeclareServiceInstanceReferenceRequestType declareServiceInstanceReferenceRequestType) throws InterruptedException
    {
        tsmController.DeclareServiceInstanceReference(this, declareServiceInstanceReferenceRequestType);
        wait();
        return displayServiceInstance;
    }

    /**
     * @param serviceInstanceReference
     * @return
     * @throws InterruptedException
     */
    public synchronized HashMap<String, String> terminateService(ServiceInstanceReferenceType serviceInstanceReference) throws InterruptedException
    {
        TerminateServiceRequestType terminateServiceRequestType = new TerminateServiceRequestType();
        terminateServiceRequestType.FunctionCallIdentifier = GpFunctions.TerminateService.getFunction();
        terminateServiceRequestType.ValidityPeriod = new BigInteger("6000");
        terminateServiceRequestType.ServiceInstanceReference = serviceInstanceReference;

        //tsmController.TerminateService(this,terminateServiceRequestType); //TODO Fonction à coder par Anne-Marie
        wait();
        return displayTerminateService;
    }

    /**
     * @param service
     * @param newService      TRUE is the service is new, FALSE if not
     * @param serviceCommands
     */
    public synchronized HashMap<String, String> upgradeService(ServiceInstanceReferenceType service, boolean newService, ArrayList<ServiceCommandType> serviceCommands)
    {
        UpgradeServiceRequestType upgradeService = new UpgradeServiceRequestType();
        upgradeService.FunctionCallIdentifier = GpFunctions.UpgradeService.getFunction();
        upgradeService.ValidityPeriod = new BigInteger("60000");
        if (newService == true)
        {
            upgradeService.NewServiceInstanceReference = service;
        } else
        {
            upgradeService.CurrentServiceInstanceReference = service;
        }
        upgradeService.ServiceCommand = serviceCommands;

        return displayUpgradeService;
    }

    /**
     * Handle the response in the callback for the Declare Service Instance Reference webservice
     *
     * @param operationResult the Operation result of the webservice
     */
    private synchronized void getDeclareServiceInstanceReferenceResponse(OperationResult operationResult)
    {
        displayServiceInstance = TSMHelperTools.handleResponse(operationResult, GpFunctions.DeclareServiceInstanceReference.getFunction());
        DeclareServiceInstanceReferenceResponseType response = (DeclareServiceInstanceReferenceResponseType) operationResult.Result;
        DeclareServiceInstanceReferenceResponseDataType responseData = response.ResponseData;
        displayServiceInstance.put("Service Instance State", tools.getStringFromServiceInstanceState(responseData.ServiceInstanceState));
    }

}
